package dziennik;

import Database.SQLInterface;
import javafx.scene.text.Font;
import java.sql.SQLException;
import java.text.DecimalFormat;
import java.text.Format;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.collections.ObservableMap;
import javafx.concurrent.Task;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXMLLoader;
import javafx.geometry.Pos;
import javafx.geometry.Side;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.chart.LineChart;
import javafx.scene.control.Button;
import javafx.scene.control.CheckBox;
import javafx.scene.control.Label;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.control.MenuButton;
import javafx.scene.control.MenuItem;
import javafx.scene.control.PasswordField;
import javafx.scene.control.SelectionMode;
import javafx.scene.control.TabPane;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.scene.control.ToggleButton;
import javafx.scene.control.ToggleGroup;
import javafx.scene.control.ToolBar;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.AnchorPane;
import javafx.scene.paint.Color;
import javafx.scene.text.FontWeight;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import javafx.util.Callback;

public class GUI_Uczen extends GUI {
    // <editor-fold defaultstate="collapsed" desc="Zmienne GUI_Uczen">

    Scene scene_uczen;
    AnchorPane ladowanie;
    AnchorPane okno;
    OknoOceny okno_oceny;
    OknoUwagi okno_uwagi;
    OknoWiadomosci okno_wiadomosci;
    OknoPlanLekcji okno_planlekcji;
    OknoOcenyKoncowe okno_ocenykoncowe;
    ToggleButton ToggleButton_Oceny;
    ToggleButton ToggleButton_Uwagi;
    ToggleButton ToggleButton_Wiadomosci;
    ToggleButton ToggleButton_PlanLekcji;
    ToggleButton ToggleButton_OcenyKoncowe;
    MenuButton MenuButton_ImieNazwisko;
    MenuItem MenuItem_Odswiez;
    MenuItem MenuItem_ZmienHaslo;
    MenuItem MenuItem_Wyloguj;
    // <editor-fold defaultstate="collapsed" desc="EventHandlery dla przycisków u góry">
    EventHandler<ActionEvent> handler_tb_oceny = new EventHandler<ActionEvent>() {
        @Override
        public void handle(ActionEvent event) {
            WyswietlOceny();
        }
    };
    EventHandler<ActionEvent> handler_tb_ocenykoncowe = new EventHandler<ActionEvent>() {
        @Override
        public void handle(ActionEvent event) {
            WyswietlOcenyKoncowe();
        }
    };
    EventHandler<ActionEvent> handler_tb_planlekcji = new EventHandler<ActionEvent>() {
        @Override
        public void handle(ActionEvent event) {
            WyswietlPlanLekcji();
        }
    };
    EventHandler<ActionEvent> handler_tb_uwagi = new EventHandler<ActionEvent>() {
        @Override
        public void handle(ActionEvent event) {
            WyswietlUwagi();
        }
    };
    EventHandler<ActionEvent> handler_tb_wiadomosci = new EventHandler<ActionEvent>() {
        @Override
        public void handle(ActionEvent event) {
            WyswietlWiadomosci();
        }
    };
    EventHandler<ActionEvent> handler_mi_odswiez = new EventHandler<ActionEvent>() {
        @Override
        public void handle(ActionEvent event) {
            try {
                AnchorPane temp = (AnchorPane) okno.getChildren().get(0);
                okno.getChildren().remove(0);
                okno.getChildren().add(ladowanie);
                okno_oceny.Odswiez();
                okno_uwagi.Odswiez();
                okno_wiadomosci.Odswiez();
                okno_planlekcji.Odswiez();
                okno_ocenykoncowe.Odswiez();
                okno.getChildren().remove(0);
                okno.getChildren().add(temp);
            } catch (Exception e) {
            }
        }
    };
    EventHandler<ActionEvent> handler_mi_zmienhaslo = new EventHandler<ActionEvent>() {
        @Override
        public void handle(ActionEvent event) {
            try {
                OknoZmianyHasla okno = new OknoZmianyHasla();
            } catch (Exception e) {
            }
        }
    };
    EventHandler<ActionEvent> handler_mi_wyloguj = new EventHandler<ActionEvent>() {
        @Override
        public void handle(ActionEvent event) {
            SQLInterface.Logout();
            Main.rst.set(!Main.rst.get());
        }
    };
    // </editor-fold>    
    // </editor-fold>    

    public GUI_Uczen(Stage s) throws Exception {
        super(s);

        parent = FXMLLoader.load(getClass().getResource("/gui_fxml/uczen.fxml"));
        ladowanie = FXMLLoader.load(getClass().getResource("/gui_fxml/login_ladowanie.fxml"));
        okno_oceny = new OknoOceny();
        okno_uwagi = new OknoUwagi();
        okno_wiadomosci = new OknoWiadomosci();
        okno_ocenykoncowe = new OknoOcenyKoncowe();
        okno_planlekcji = new OknoPlanLekcji();


        ToolBar tb = (ToolBar) parent.getChildren().get(0);
        okno = (AnchorPane) parent.getChildren().get(1);

        ToggleButton_Oceny = (ToggleButton) tb.getItems().get(0);
        ToggleButton_Uwagi = (ToggleButton) tb.getItems().get(1);
        ToggleButton_Wiadomosci = (ToggleButton) tb.getItems().get(2);
        ToggleButton_PlanLekcji = (ToggleButton) tb.getItems().get(3);
        ToggleButton_OcenyKoncowe = (ToggleButton) tb.getItems().get(4);
        MenuButton_ImieNazwisko = (MenuButton) tb.getItems().get(5);

        ToggleGroup tg = new ToggleGroup();
        ToggleButton_Oceny.setToggleGroup(tg);
        ToggleButton_Uwagi.setToggleGroup(tg);
        ToggleButton_Wiadomosci.setToggleGroup(tg);
        ToggleButton_PlanLekcji.setToggleGroup(tg);
        ToggleButton_OcenyKoncowe.setToggleGroup(tg);

        ToggleButton_Oceny.setSelected(true);

        ToggleButton_Oceny.setOnAction(handler_tb_oceny);
        ToggleButton_OcenyKoncowe.setOnAction(handler_tb_ocenykoncowe);
        ToggleButton_PlanLekcji.setOnAction(handler_tb_planlekcji);
        ToggleButton_Uwagi.setOnAction(handler_tb_uwagi);
        ToggleButton_Wiadomosci.setOnAction(handler_tb_wiadomosci);
        MenuItem_Odswiez = MenuButton_ImieNazwisko.getItems().get(0);
        MenuItem_ZmienHaslo = MenuButton_ImieNazwisko.getItems().get(1);
        MenuItem_Wyloguj = MenuButton_ImieNazwisko.getItems().get(2);

        MenuItem_Odswiez.setOnAction(handler_mi_odswiez);
        MenuItem_Wyloguj.setOnAction(handler_mi_wyloguj);
        MenuItem_ZmienHaslo.setOnAction(handler_mi_zmienhaslo);

        String[] daneUcznia = SQLInterface.DaneOsobowe.Uczen_PobierzDaneOsobowe();
        MenuButton_ImieNazwisko.setText(daneUcznia[0] + " " + daneUcznia[1] + ", kl. " + daneUcznia[2]);
        MenuButton_ImieNazwisko.alignmentProperty().set(Pos.CENTER);
        MenuButton_ImieNazwisko.setPopupSide(Side.BOTTOM);



        stage.setTitle("Dziennik elektroniczny - widok ucznia");
        okno.getChildren().add(okno_oceny.ramka);
        scene_uczen = new Scene(parent);
        scene_uczen.getStylesheets().add(this.getClass().getResource("/gui_fxml/stylTabeli.css").toExternalForm());
        okno_oceny.Odswiez();
        okno_uwagi.Odswiez();
        okno_wiadomosci.Odswiez();
        okno_planlekcji.Odswiez();
        okno_ocenykoncowe.Odswiez();
        stage.setScene(scene_uczen);
        stage.show();
    }
    // <editor-fold defaultstate="collapsed" desc="Metody wyświetlające podokna">

    void WyswietlOceny() {
        okno.getChildren().remove(0);
        okno.getChildren().add(okno_oceny.ramka);
    }

    void WyswietlUwagi() {
        okno.getChildren().remove(0);
        okno.getChildren().add(okno_uwagi.ramka);
    }

    void WyswietlWiadomosci() {
        okno.getChildren().remove(0);
        okno.getChildren().add(okno_wiadomosci.ramka);
    }

    void WyswietlPlanLekcji() {
        okno.getChildren().remove(0);
        okno.getChildren().add(okno_planlekcji.ramka);
    }

    void WyswietlOcenyKoncowe() {
        okno.getChildren().remove(0);
        okno.getChildren().add(okno_ocenykoncowe.ramka);
    }
    // </editor-fold>

    private abstract class Okno {

        public AnchorPane ramka;
        public FXMLLoader loader;
        ObservableMap<String, Object> elementy;

        Okno(String path) {
            loader = new FXMLLoader(getClass().getResource(path));
            try {
                ramka = (AnchorPane) loader.load();
                elementy = loader.getNamespace();
            } catch (Exception e) {
                e.printStackTrace(System.out);
                System.out.println(e.getMessage());
            }
        }

        public abstract void Odswiez() throws Exception;
    }

    public class OknoOceny extends Okno {
        // <editor-fold defaultstate="collapsed" desc="Zmienne OknoOceny">

        public ListView<String> ListView_ListaPrzedmiotow;
        public Label Label_ImieNazwiskoNauczyciela;
        public Label Label_SredniaOcen;
        public TableView<OknoOceny.RekordTabeliOcen> TableView_TabelaOcen;
        public TableColumn TableColumn_Data;
        public TableColumn TableColumn_Ocena;
        public TableColumn TableColumn_Waga;
        public TableColumn TableColumn_ZaCo;
        public LineChart<String, Number> LineChart_WykresSredniej;
        public ArrayList<SQLInterface.Oceny.Ocena_DlaUcznia> oceny;
        public ArrayList<SQLInterface.Przedmioty.Przedmiot_DlaUcznia> przedmioty;
        // </editor-fold>
        // <editor-fold defaultstate="collapsed" desc="EventHandler dla listy przedmiotów">
        ChangeListener<String> handler_lv_listaocen = new ChangeListener<String>() {
            @Override
            public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
                System.out.println("Selected item: " + newValue);
                try {
                    okno_oceny.OdswiezTabeleOcenIWykres(newValue);
                } catch (Exception e) {
                    System.out.println("blad handler_lv_listaocen");
                    System.out.println(e.getMessage());
                    e.printStackTrace(System.out);
                }
            }
        };
        // </editor-fold>        

        public class RekordTabeliOcen {

            private StringProperty data;
            private StringProperty ocena;
            private IntegerProperty waga;
            private StringProperty zaCo;

            RekordTabeliOcen(Date data, float ocena, int waga, String zaCo) {
                Format format = new SimpleDateFormat("yyyy-MM-dd");
                String s_ocena;
                float t = ocena - (int) ocena;
                if (t >= 0 && t <= 0.1) {//x
                    s_ocena = Integer.toString((int) ocena);
                } else if (t >= 0.1 && t <= 0.5) {//x+
                    s_ocena = Integer.toString((int) ocena) + "+";
                } else if (t >= 0.5 && t <= 0.9) {//(x+1)-
                    s_ocena = Integer.toString(((int) ocena) + 1) + "-";
                } else if (t >= 0.9 && t < 1) {//(x+1)
                    s_ocena = Integer.toString(((int) ocena) + 1);
                } else {
                    System.out.println("BLEDNA OCENA");
                    s_ocena = "0";
                }
                this.data = new SimpleStringProperty(format.format(data));
                this.ocena = new SimpleStringProperty(s_ocena);
                this.waga = new SimpleIntegerProperty(waga);
                this.zaCo = new SimpleStringProperty(zaCo);
            }//OK

            public StringProperty dataProperty() {
                return data;
            }

            public StringProperty ocenaProperty() {
                return ocena;
            }

            public IntegerProperty wagaProperty() {
                return waga;
            }

            public StringProperty zaCoProperty() {
                return zaCo;
            }
        }

        OknoOceny() {
            super("/gui_fxml/uczen_oceny.fxml");
            ListView_ListaPrzedmiotow = (ListView<String>) elementy.get("ListView_ListaPrzedmiotow");
            Label_ImieNazwiskoNauczyciela = (Label) elementy.get("Label_ImieNazwiskoNauczyciela");
            Label_SredniaOcen = (Label) elementy.get("Label_SredniaOcen");
            TableView_TabelaOcen = (TableView<GUI_Uczen.OknoOceny.RekordTabeliOcen>) elementy.get("TableView_TabelaOcen");
            LineChart_WykresSredniej = (LineChart<String, Number>) elementy.get("LineChart_WykresSredniej");
            TableColumn_Data = (TableColumn) elementy.get("TableColumn_Data");
            TableColumn_Ocena = (TableColumn) elementy.get("TableColumn_Ocena");
            TableColumn_Waga = (TableColumn) elementy.get("TableColumn_Waga");
            TableColumn_ZaCo = (TableColumn) elementy.get("TableColumn_ZaCo");

            ListView_ListaPrzedmiotow.getSelectionModel().setSelectionMode(SelectionMode.SINGLE);
            ListView_ListaPrzedmiotow.getSelectionModel().selectedItemProperty().addListener(handler_lv_listaocen);

            TableColumn_Data.setCellValueFactory(new PropertyValueFactory("data"));
            TableColumn_Ocena.setCellValueFactory(new PropertyValueFactory("ocena"));
            TableColumn_Waga.setCellValueFactory(new PropertyValueFactory("waga"));
            TableColumn_ZaCo.setCellValueFactory(new PropertyValueFactory("zaCo"));

            LineChart_WykresSredniej.setLegendVisible(false);
            try {
                Odswiez();
            } catch (Exception e) {
                System.out.println("Odswiezanie okna Oceny");
                System.out.println(e.getMessage());
                e.printStackTrace(System.out);
            }

        }

        void OdswiezListePrzedmiotow() throws Exception {
            ObservableList<String> listaPrzedmiotow = FXCollections.observableArrayList();
            for (SQLInterface.Przedmioty.Przedmiot_DlaUcznia p : przedmioty) {
                listaPrzedmiotow.add(p.nazwa);
            }
            ListView_ListaPrzedmiotow.setItems(listaPrzedmiotow);
        }//OK

        void OdswiezTabeleOcenIWykres(String nazwaPrzedmiotu) throws Exception {
            //wydaje sie byc ok
            if (nazwaPrzedmiotu == null || "".equals(nazwaPrzedmiotu)) {
                return;
            }
            System.out.println(nazwaPrzedmiotu);
            final ObservableList<OknoOceny.RekordTabeliOcen> daneDoTabeli = FXCollections.observableArrayList();
            for (SQLInterface.Oceny.Ocena_DlaUcznia o : oceny) {
                if (o.nazwaPrzedmiotu.equals(nazwaPrzedmiotu)) {
                    daneDoTabeli.add(new OknoOceny.RekordTabeliOcen(o.data, o.ocena, o.waga, o.zaCo));
                }
            }//mamy kolekcję ocen z wyznaczonego przedmiotu o nazwie daneDoTabeli

            TableView_TabelaOcen.setItems(daneDoTabeli);


            //odtad zaczyna sie wykres
            Format format = new SimpleDateFormat("yyyy-MM-dd");
            Format formatSredniej = new DecimalFormat("#.##");

            LineChart_WykresSredniej.getData().clear();
            LineChart.Series<String, Number> daneWykresu = new LineChart.Series<String, Number>();
            daneWykresu.setName("Średnia");

            float sumaOcen = 0;
            float sumaWag = 0;
            float srednia = 0;

            for (int i = 0; i != daneDoTabeli.size(); i++) {
                sumaOcen += oceny.get(i).ocena * (float) oceny.get(i).waga;
                sumaWag += oceny.get(i).waga;
                srednia = sumaOcen / sumaWag;
                LineChart.Data<String, Number> punktWykresu = new LineChart.Data<String, Number>(format.format(oceny.get(i).data), srednia);
                daneWykresu.getData().add(punktWykresu);
            }
            LineChart_WykresSredniej.getData().add(daneWykresu);
            Label_SredniaOcen.setText(formatSredniej.format(srednia));
            int i = 0;
            while (i != przedmioty.size()) {
                if (przedmioty.get(i).nazwa.equalsIgnoreCase(nazwaPrzedmiotu)) {
                    break;
                }
                i++;
            }
            //koniec wykresu
            Label_ImieNazwiskoNauczyciela.setText(przedmioty.get(i).nazwa
                    + " - "
                    + przedmioty.get(i).tytulNaukowy
                    + " "
                    + przedmioty.get(i).imie
                    + " "
                    + przedmioty.get(i).nazwisko);
        }

        @Override
        public final void Odswiez() throws Exception {
            oceny = SQLInterface.Oceny.PobierzOcenyUcznia();
            przedmioty = SQLInterface.Przedmioty.PobierzPrzedmiotyUcznia();
            OdswiezListePrzedmiotow();
        }
    }

    public class OknoUwagi extends Okno {
        // <editor-fold defaultstate="collapsed" desc="Zmienne OknoUwagi">

        public ArrayList<SQLInterface.Uwagi.Uwaga> uwagi;
        public TableView<OknoUwagi.RekordTabeliUwag> TableView_TabelaUwag;
        public TextArea TextArea_TrescUwagi;
        public TableColumn TableColumn_Data;
        public TableColumn TableColumn_WystawionePrzez;
        // </editor-fold>
        // <editor-fold defaultstate="collapsed" desc="EventHandler dla listy uwag">
        ChangeListener<RekordTabeliUwag> handler_tv_listauwag = new ChangeListener<RekordTabeliUwag>() {
            @Override
            public void changed(ObservableValue<? extends RekordTabeliUwag> observable, RekordTabeliUwag oldValue, RekordTabeliUwag newValue) {
                try {
                    OdswiezTrescUwagi(newValue);
                } catch (Exception e) {
                    System.out.println("blad handler_lv_listaocen");
                    System.out.println(e.getMessage());
                    e.printStackTrace(System.out);
                }
            }
        };
        // </editor-fold>

        OknoUwagi() {
            super("/gui_fxml/uczen_uwagi.fxml");
            TableView_TabelaUwag = (TableView) elementy.get("TableView_TabelaUwag");
            TextArea_TrescUwagi = (TextArea) elementy.get("TextArea_TrescUwagi");
            TableColumn_Data = (TableColumn) elementy.get("TableColumn_Data");
            TableColumn_WystawionePrzez = (TableColumn) elementy.get("TableColumn_WystawionePrzez");

            TableView_TabelaUwag.getSelectionModel().setSelectionMode(SelectionMode.SINGLE);
            TableView_TabelaUwag.getSelectionModel().selectedItemProperty().addListener(handler_tv_listauwag);

            TableColumn_Data.setCellValueFactory(new PropertyValueFactory("data"));
            TableColumn_WystawionePrzez.setCellValueFactory(new PropertyValueFactory("wystawionePrzez"));
            try {
                Odswiez();
            } catch (Exception e) {
                System.out.println("Odswiezanie okna Uwagi");
                System.out.println(e.getMessage());
                e.printStackTrace(System.out);
            }
        }

        @Override
        public final void Odswiez() throws Exception {
            uwagi = SQLInterface.Uwagi.PobierzUwagiUcznia();
            OdswiezListeUwag();
        }

        void OdswiezListeUwag() throws Exception {
            final ObservableList<RekordTabeliUwag> daneDoTabeli = FXCollections.observableArrayList();
            for (SQLInterface.Uwagi.Uwaga u : uwagi) {
                RekordTabeliUwag r = new RekordTabeliUwag(u.data, u.wystawiajacy, u.tresc);
                daneDoTabeli.add(r);
            }//mamy kolekcję ocen z wyznaczonego przedmiotu o nazwie daneDoTabeli
            TableView_TabelaUwag.setItems(daneDoTabeli);
        }

        void OdswiezTrescUwagi(RekordTabeliUwag uwaga) throws Exception {
            TextArea_TrescUwagi.setText(uwaga.getTresc());
        }

        public class RekordTabeliUwag {

            private StringProperty data;
            private StringProperty wystawionePrzez;
            private String tresc;

            RekordTabeliUwag(Date data, String wystawionePrzez, String tresc) {
                Format format = new SimpleDateFormat("yyyy-MM-dd");
                this.data = new SimpleStringProperty(format.format(data));
                this.wystawionePrzez = new SimpleStringProperty(wystawionePrzez);
                this.tresc = tresc;
            }

            public StringProperty dataProperty() {
                return data;
            }

            public StringProperty wystawionePrzezProperty() {
                return wystawionePrzez;
            }

            public String getTresc() {
                return tresc;
            }
        }
    }

    public class OknoWiadomosci extends Okno {
        // <editor-fold defaultstate="collapsed" desc="Zmienne OknoWiadomosci">
        // <editor-fold defaultstate="expanded" desc="Zakładka Odebrane">

        public TabPane TabPane_Zakladki;
        public Button Button_Odebrane_Odpowiedz;
        public Button Button_Odebrane_Usun;
        public Button Button_Odebrane_OznaczJakoPrzeczytane;
        public TextField TextField_Odebrane_Od;
        public TextField TextField_Odebrane_Temat;
        public TextArea TextArea_Odebrane_Tresc;
        public CheckBox CheckBox_Odebrane_ZaznaczWszystkie;
        public TableView<Wiadomosc> TableViev_Odebrane_TabelaWiadomosci;
        public TableColumn<Wiadomosc, Boolean> TableColumn_Odebrane_Zaznaczona;
        public TableColumn<Wiadomosc, String> TableColumn_Odebrane_Przeczytana;
        public TableColumn TableColumn_Odebrane_Otrzymano;
        public TableColumn TableColumn_Odebrane_Nadawca;
        public TableColumn TableColumn_Odebrane_Temat;
        // </editor-fold>
        // <editor-fold defaultstate="expanded" desc="Zakładka Wyślij">
        public ListView<SQLInterface.Nauczyciele.Nauczyciel_DlaUcznia> ListView_Napisz_TwoiNauczyciele;
        public ListView<SQLInterface.Nauczyciele.Nauczyciel_DlaUcznia> ListView_Napisz_PozostaliNauczyciele;
        public TextField TextField_Napisz_Temat;
        public TextArea TextArea_Napisz_Tresc;
        public Button Button_Napisz_Wyslij;
        public BooleanProperty podanyAdresat = new SimpleBooleanProperty(false);
        public BooleanProperty podanyTemat = new SimpleBooleanProperty(false);
        public BooleanProperty podanaTresc = new SimpleBooleanProperty(false);
        public int idAdresata = -1;
        // </editor-fold>
        ObservableList<Wiadomosc> wiadomosci;
        // <editor-fold defaultstate="collapsed" desc="EventHandlery">
        ChangeListener<Wiadomosc> handler_tv_listawiadomosci = new ChangeListener<Wiadomosc>() {
            @Override
            public void changed(ObservableValue<? extends Wiadomosc> observable, Wiadomosc oldValue, Wiadomosc newValue) {
                try {
                    TextField_Odebrane_Od.setText(newValue.nadawca.get());
                    TextField_Odebrane_Temat.setText(newValue.temat.get());
                    TextArea_Odebrane_Tresc.setText(newValue.tresc.get());
                    final Wiadomosc w = newValue;
                    System.out.println(w.przeczytana + " " + w.id);
                    Task<Void> bgTask = new Task<Void>() {
                        @Override
                        protected Void call() throws Exception {
                            SQLInterface.Wiadomosci.OznaczJakoPrzeczytane(w.id.get());
                            w.przeczytana.set("");
                            System.out.println("watek ok");

                            return null;
                        }
                    };
                    new Thread(bgTask).start();
                } catch (Exception e) {
                    System.out.println("blad handler_lv_listawiadomosci");
                    System.out.println(e.getMessage());
                    e.printStackTrace(System.out);
                }
            }
        };
        ChangeListener<String> handler_tf_wyslij_temat = new ChangeListener<String>() {
            @Override
            public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
                if (newValue.equals("") || newValue.isEmpty() || newValue.matches("") || newValue == null) {
                    podanyTemat.set(false);
                    System.out.println("temat: pusta");
                } else {
                    podanyTemat.set(true);
                    System.out.println("temat: jest");
                }
                OdswiezButtonWyslij();
                //System.out.println("temat");
            }
        };
        ChangeListener<String> handler_tf_wyslij_tresc = new ChangeListener<String>() {
            @Override
            public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
                if (newValue.equals("") || newValue.isEmpty() || newValue.matches("") || newValue == null) {
                    podanaTresc.set(false);
                    System.out.println("tresc: pusta");
                } else {
                    podanaTresc.set(true);
                }
                OdswiezButtonWyslij();
                System.out.println("tresc: jest");
            }
        };
        ChangeListener<SQLInterface.Nauczyciele.Nauczyciel_DlaUcznia> handler_lv_wyslij_adresat = new ChangeListener<SQLInterface.Nauczyciele.Nauczyciel_DlaUcznia>() {
            @Override
            public void changed(ObservableValue<? extends SQLInterface.Nauczyciele.Nauczyciel_DlaUcznia> observable, SQLInterface.Nauczyciele.Nauczyciel_DlaUcznia oldValue, SQLInterface.Nauczyciele.Nauczyciel_DlaUcznia newValue) {
                ListView_Napisz_PozostaliNauczyciele.getSelectionModel().clearSelection();
                if (ListView_Napisz_TwoiNauczyciele.getSelectionModel().isEmpty() && ListView_Napisz_PozostaliNauczyciele.getSelectionModel().isEmpty()) {
                    podanyAdresat.set(false);
                    System.out.println("adresat: brak");
                    idAdresata = -1;
                } else {
                    podanyAdresat.set(true);
                    idAdresata = newValue.userId;
                    System.out.println("adresat: jest");
                }
                OdswiezButtonWyslij();
                //System.out.println("adresat");
            }
        };
        EventHandler<ActionEvent> handler_cb_zaznaczwszystkie = new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                for (Wiadomosc w : wiadomosci) {
                    w.zaznaczona.set(CheckBox_Odebrane_ZaznaczWszystkie.selectedProperty().get());
                }
            }
        };
        EventHandler<ActionEvent> handler_bt_oznaczjakoprzeczytane = new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                final ArrayList<Integer> listaIndeksow = new ArrayList<Integer>();
                for (Wiadomosc w : wiadomosci) {
                    if (w.zaznaczonaProperty().get()) {
                        w.przeczytanaProperty().set("");
                        listaIndeksow.add(w.idProperty().get());
                    }
                }
                if (!listaIndeksow.isEmpty()) {
                    Task<Void> bgTask = new Task<Void>() {
                        @Override
                        protected Void call() throws Exception {
                            SQLInterface.Wiadomosci.OznaczJakoPrzeczytane(listaIndeksow);
                            return null;
                        }
                    };
                    new Thread(bgTask).start();
                }
            }
        };
        EventHandler<ActionEvent> handler_bt_usun = new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                final ArrayList<Integer> listaIndeksow = new ArrayList<>();
                final ArrayList<Wiadomosc> doUsuniecia = new ArrayList<>();
                for (int i = 0; i != wiadomosci.size(); i++) {
                    if (wiadomosci.get(i).zaznaczonaProperty().get()) {
                        listaIndeksow.add(wiadomosci.get(i).idProperty().get());
                        doUsuniecia.add(wiadomosci.get(i));
                    }

                }
                for (Wiadomosc w : doUsuniecia) {
                    wiadomosci.remove(w);
                }
                if (!listaIndeksow.isEmpty()) {
                    try {
                        SQLInterface.Wiadomosci.Usun(listaIndeksow);
                    } catch (Exception e) {
                        System.out.println("masowe usuwanie wiadomosci");
                    }

                }
            }
        };
        EventHandler<ActionEvent> handler_bt_odpowiedz = new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                if(TableViev_Odebrane_TabelaWiadomosci.getSelectionModel().getSelectedIndices().isEmpty()){return;}
                int odbiorca = TableViev_Odebrane_TabelaWiadomosci.getSelectionModel().getSelectedItem().idNadawcy.get();
                String temat = "Odp: " + TableViev_Odebrane_TabelaWiadomosci.getSelectionModel().getSelectedItem().tematProperty().get();

                TabPane_Zakladki.getSelectionModel().select(1);
                TextField_Napisz_Temat.setText(temat);
                TextArea_Napisz_Tresc.setText("");
                Runnable przekazFocus = new Runnable() {
                    @Override
                    public void run() {
                        try {
                            Thread.sleep(100);
                        } catch (Exception e) {
                        }
                        TextArea_Napisz_Tresc.requestFocus();
                    }
                };
                boolean znaleziony = false;
                for (int i = 0; i != ListView_Napisz_TwoiNauczyciele.getItems().size(); i++) {
                    if (ListView_Napisz_TwoiNauczyciele.getItems().get(i).userId == odbiorca) {
                        ListView_Napisz_TwoiNauczyciele.getSelectionModel().select(i);
                        znaleziony = true;
                        break;
                    }
                }
                if (!znaleziony) {
                    for (int i = 0; i != ListView_Napisz_PozostaliNauczyciele.getItems().size(); i++) {
                        if (ListView_Napisz_PozostaliNauczyciele.getItems().get(i).userId == odbiorca) {
                            ListView_Napisz_PozostaliNauczyciele.getSelectionModel().select(i);
                            znaleziony = true;
                            break;
                        }
                    }
                }
                if (!znaleziony) {
                    System.out.println("cos jest nie tak");
                } else {
                    javafx.application.Platform.runLater(przekazFocus);
                }
            }
        };
        EventHandler<ActionEvent> handler_bt_wyslij = new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                boolean pierwszaLista = !ListView_Napisz_TwoiNauczyciele.getSelectionModel().isEmpty();
                boolean drugaLista = !ListView_Napisz_PozostaliNauczyciele.getSelectionModel().isEmpty();
                try {
                    SQLInterface.Wiadomosci.Wyslij(TextField_Napisz_Temat.getText(), TextArea_Napisz_Tresc.getText(), idAdresata);
                    TextField_Napisz_Temat.clear();
                    TextArea_Napisz_Tresc.clear();
                } catch (SQLException e) {
                    System.out.println("Blad SQL wysylania wiadomosci: " + e.getMessage());
                }
            }
        };
        // </editor-fold>
        // <editor-fold defaultstate="collapsed" desc="CellFactory">
        Callback callback_zaznaczone = new Callback<TableColumn<Wiadomosc, Boolean>, TableCell<Wiadomosc, Boolean>>() {
            @Override
            public TableCell<Wiadomosc, Boolean> call(TableColumn<Wiadomosc, Boolean> p) {
                return new CheckBoxTableCell<>();
            }
        };
        Callback callback_nauczyciele = new Callback<ListView<SQLInterface.Nauczyciele.Nauczyciel_DlaUcznia>, ListCell<SQLInterface.Nauczyciele.Nauczyciel_DlaUcznia>>() {
            @Override
            public ListCell<SQLInterface.Nauczyciele.Nauczyciel_DlaUcznia> call(ListView<SQLInterface.Nauczyciele.Nauczyciel_DlaUcznia> list) {
                return new KomorkaListyNauczycieli();
            }
        };

        // </editor-fold>
        // </editor-fold>
        OknoWiadomosci() {
            super("/gui_fxml/uczen_wiadomosci.fxml");
            TabPane_Zakladki = (TabPane) elementy.get("TabPane_Zakladki");

            Button_Odebrane_Odpowiedz = (Button) elementy.get("Button_Odebrane_Odpowiedz");
            Button_Odebrane_Usun = (Button) elementy.get("Button_Odebrane_Usun");
            Button_Odebrane_OznaczJakoPrzeczytane = (Button) elementy.get("Button_Odebrane_OznaczJakoPrzeczytane");
            TextField_Odebrane_Od = (TextField) elementy.get("TextField_Odebrane_Od");
            TextField_Odebrane_Temat = (TextField) elementy.get("TextField_Odebrane_Temat");
            TextArea_Odebrane_Tresc = (TextArea) elementy.get("TextArea_Odebrane_Tresc");
            CheckBox_Odebrane_ZaznaczWszystkie = (CheckBox) elementy.get("CheckBox_Odebrane_ZaznaczWszystkie");
            TableViev_Odebrane_TabelaWiadomosci = (TableView) elementy.get("TableView_Odebrane_TabelaWiadomosci");
            TableColumn_Odebrane_Zaznaczona = (TableColumn<Wiadomosc, Boolean>) elementy.get("TableColumn_Odebrane_Zaznaczona");
            TableColumn_Odebrane_Przeczytana = (TableColumn<Wiadomosc, String>) elementy.get("TableColumn_Odebrane_Przeczytana");
            TableColumn_Odebrane_Otrzymano = (TableColumn) elementy.get("TableColumn_Odebrane_Otrzymano");
            TableColumn_Odebrane_Nadawca = (TableColumn) elementy.get("TableColumn_Odebrane_Nadawca");
            TableColumn_Odebrane_Temat = (TableColumn) elementy.get("TableColumn_Odebrane_Temat");
            ListView_Napisz_TwoiNauczyciele = (ListView) elementy.get("ListView_Napisz_TwoiNauczyciele");
            ListView_Napisz_PozostaliNauczyciele = (ListView) elementy.get("ListView_Napisz_PozostaliNauczyciele");
            TextField_Napisz_Temat = (TextField) elementy.get("TextField_Napisz_Temat");
            TextArea_Napisz_Tresc = (TextArea) elementy.get("TextArea_Napisz_Tresc");
            Button_Napisz_Wyslij = (Button) elementy.get("Button_Napisz_Wyslij");

            TableViev_Odebrane_TabelaWiadomosci.getSelectionModel().setSelectionMode(SelectionMode.SINGLE);
            TableViev_Odebrane_TabelaWiadomosci.getSelectionModel().selectedItemProperty().addListener(handler_tv_listawiadomosci);
            TableColumn_Odebrane_Nadawca.setCellValueFactory(new PropertyValueFactory("nadawca"));
            TableColumn_Odebrane_Temat.setCellValueFactory(new PropertyValueFactory("temat"));
            TableColumn_Odebrane_Otrzymano.setCellValueFactory(new PropertyValueFactory("otrzymano"));

            TableColumn_Odebrane_Przeczytana.setCellValueFactory(new PropertyValueFactory("przeczytana"));
            TableColumn_Odebrane_Zaznaczona.setCellValueFactory(new PropertyValueFactory("zaznaczona"));
            TableColumn_Odebrane_Zaznaczona.setCellFactory(callback_zaznaczone);

            CheckBox_Odebrane_ZaznaczWszystkie.setOnAction(handler_cb_zaznaczwszystkie);
            Button_Odebrane_OznaczJakoPrzeczytane.setOnAction(handler_bt_oznaczjakoprzeczytane);
            Button_Odebrane_Usun.setOnAction(handler_bt_usun);
            Button_Odebrane_Odpowiedz.setOnAction(handler_bt_odpowiedz);
            Button_Napisz_Wyslij.setOnAction(handler_bt_wyslij);
            ListView_Napisz_PozostaliNauczyciele.setCellFactory(callback_nauczyciele);
            ListView_Napisz_TwoiNauczyciele.setCellFactory(callback_nauczyciele);

            TextField_Napisz_Temat.textProperty().addListener(handler_tf_wyslij_temat);
            TextArea_Napisz_Tresc.textProperty().addListener(handler_tf_wyslij_tresc);
            ListView_Napisz_TwoiNauczyciele.getSelectionModel().selectedItemProperty().addListener(handler_lv_wyslij_adresat);
            ListView_Napisz_PozostaliNauczyciele.getSelectionModel().selectedItemProperty().addListener(handler_lv_wyslij_adresat);
            try {
                Odswiez();
            } catch (Exception e) {
                System.out.println("Odswiezanie okna Wiadomosci");
                System.out.println(e.getMessage());
                e.printStackTrace(System.out);
            }

        }

        void OdswiezButtonWyslij() {
            System.out.println("sprawdzam: " + podanaTresc.get() + podanyAdresat.get() + podanyTemat.get());
            if (podanaTresc.get() && podanyAdresat.get() && podanyTemat.get()) {
                Button_Napisz_Wyslij.setDisable(false);
            } else {
                Button_Napisz_Wyslij.setDisable(true);
            }
        }

        @Override
        final public void Odswiez() throws Exception {
            OdswiezTabeleWiadomosci();
            OdswiezListeNauczycieli();
        }

        void OdswiezTabeleWiadomosci() throws Exception {
            ArrayList<SQLInterface.Wiadomosci.Wiadomosc> pobraneWiadomosci = SQLInterface.Wiadomosci.PobierzWiadomosci();
            wiadomosci = FXCollections.observableArrayList();

            for (SQLInterface.Wiadomosci.Wiadomosc w : pobraneWiadomosci) {
                wiadomosci.add(new Wiadomosc(w));
            }
            TableViev_Odebrane_TabelaWiadomosci.setItems(wiadomosci);
        }

        void OdswiezListeNauczycieli() throws Exception {
            ObservableList<SQLInterface.Nauczyciele.Nauczyciel_DlaUcznia> listaTwoichNauczycieli = FXCollections.observableArrayList();
            ObservableList<SQLInterface.Nauczyciele.Nauczyciel_DlaUcznia> listaPozostalychNauczycieli = FXCollections.observableArrayList();
            ArrayList<SQLInterface.Nauczyciele.Nauczyciel_DlaUcznia> pobraniNauczyciele = SQLInterface.Nauczyciele.PobierzListeNauczycieli();
            for (SQLInterface.Nauczyciele.Nauczyciel_DlaUcznia n : pobraniNauczyciele) {
                if (n.twojNauczyciel) {
                    listaTwoichNauczycieli.add(n);
                } else {
                    listaPozostalychNauczycieli.add(n);
                }
            }
            ListView_Napisz_TwoiNauczyciele.setItems(listaTwoichNauczycieli);
            ListView_Napisz_PozostaliNauczyciele.setItems(listaPozostalychNauczycieli);
        }

        public class Wiadomosc {

            private BooleanProperty zaznaczona;
            private StringProperty przeczytana;
            private IntegerProperty id;
            private IntegerProperty idNadawcy;
            private StringProperty otrzymano;
            private StringProperty nadawca;
            private StringProperty temat;
            private StringProperty tresc;

            public Wiadomosc(SQLInterface.Wiadomosci.Wiadomosc w) {
                Format format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                zaznaczona = new SimpleBooleanProperty(false);
                przeczytana = new SimpleStringProperty("");
                if (!w.przeczytane) {
                    przeczytana.set("\u26AB");
                }
                id = new SimpleIntegerProperty(w.id);

                idNadawcy = new SimpleIntegerProperty(w.idNadawcy);
                otrzymano = new SimpleStringProperty(format.format(w.czas));
                nadawca = new SimpleStringProperty(w.nadawca);
                temat = new SimpleStringProperty(w.temat);
                tresc = new SimpleStringProperty(w.tresc);
            }

            public BooleanProperty zaznaczonaProperty() {
                return zaznaczona;
            }

            public void setZaznaczona(Boolean z) {
                zaznaczona.set(z);
            }

            public void setPrzeczytana(Boolean p) {
                if (p) {
                    przeczytana.set("");
                } else {
                    przeczytana.set("\u26AB");
                }
            }

            public StringProperty przeczytanaProperty() {
                return przeczytana;
            }

            public IntegerProperty idProperty() {
                return id;
            }

            public IntegerProperty idNadawcyProperty() {
                return idNadawcy;
            }

            public StringProperty otrzymanoProperty() {
                return otrzymano;
            }

            public StringProperty nadawcaProperty() {
                return nadawca;
            }

            public StringProperty tematProperty() {
                return temat;
            }

            public StringProperty trescProperty() {
                return tresc;
            }
        }

        public class CheckBoxTableCell<S, T> extends TableCell<S, T> {

            private final CheckBox checkBox;
            private ObservableValue<T> ov;

            public CheckBoxTableCell() {
                this.checkBox = new CheckBox();
                /*this.checkBox.setAlignment(Pos.CENTER);
                 setAlignment(Pos.CENTER);*/
                setGraphic(checkBox);
            }

            @Override
            public void updateItem(T item, boolean empty) {
                super.updateItem(item, empty);
                if (empty) {
                    setText(null);
                    setGraphic(null);
                } else {
                    setGraphic(checkBox);
                    if (ov instanceof BooleanProperty) {
                        checkBox.selectedProperty().unbindBidirectional((BooleanProperty) ov);
                    }
                    ov = getTableColumn().getCellObservableValue(getIndex());
                    if (ov instanceof BooleanProperty) {
                        checkBox.selectedProperty().bindBidirectional((BooleanProperty) ov);
                    }
                }
            }
        }

        public class KomorkaListyNauczycieli extends ListCell<SQLInterface.Nauczyciele.Nauczyciel_DlaUcznia> {

            @Override
            public void updateItem(SQLInterface.Nauczyciele.Nauczyciel_DlaUcznia item, boolean empty) {
                super.updateItem(item, empty);
                if (!empty) {
                    setText(item.nazwisko + " " + item.imie + ", " + item.tytulNaukowy);
                }
            }
        }
    }

    public class OknoPlanLekcji extends Okno {

        TableView<RzadTabeliPlanuLekcji> TableView_PlanLekcji;
        TableColumn<RzadTabeliPlanuLekcji, String> TableColumn_Godzina;
        TableColumn<RzadTabeliPlanuLekcji, String> TableColumn_Poniedzialek;
        TableColumn<RzadTabeliPlanuLekcji, String> TableColumn_Wtorek;
        TableColumn<RzadTabeliPlanuLekcji, String> TableColumn_Sroda;
        TableColumn<RzadTabeliPlanuLekcji, String> TableColumn_Czwartek;
        TableColumn<RzadTabeliPlanuLekcji, String> TableColumn_Piatek;
        ObservableList<RzadTabeliPlanuLekcji> listaTwoichNauczycieli;
        Callback<TableColumn<RzadTabeliPlanuLekcji, String>, TableCell<RzadTabeliPlanuLekcji, String>> godzinaFactory =
                new Callback<TableColumn<RzadTabeliPlanuLekcji, String>, TableCell<RzadTabeliPlanuLekcji, String>>() {
                    @Override
                    public TableCell call(TableColumn p) {
                        return new KomorkaGodziny();
                    }
                };
        Callback<TableColumn<RzadTabeliPlanuLekcji, String>, TableCell<RzadTabeliPlanuLekcji, String>> przedmiotFactory =
                new Callback<TableColumn<RzadTabeliPlanuLekcji, String>, TableCell<RzadTabeliPlanuLekcji, String>>() {
                    @Override
                    public TableCell call(TableColumn p) {
                        return new KomorkaPlanuLekcji();
                    }
                };

        OknoPlanLekcji() {
            super("/gui_fxml/uczen_planlekcji.fxml");
            TableView_PlanLekcji = (TableView<RzadTabeliPlanuLekcji>) elementy.get("TableView_PlanLekcji");
            TableColumn_Godzina = (TableColumn) elementy.get("TableColumn_Godzina");
            TableColumn_Poniedzialek = (TableColumn) elementy.get("TableColumn_Poniedzialek");
            TableColumn_Wtorek = (TableColumn) elementy.get("TableColumn_Wtorek");
            TableColumn_Sroda = (TableColumn) elementy.get("TableColumn_Sroda");
            TableColumn_Czwartek = (TableColumn) elementy.get("TableColumn_Czwartek");
            TableColumn_Piatek = (TableColumn) elementy.get("TableColumn_Piatek");

            TableColumn_Godzina.setCellValueFactory(new PropertyValueFactory("godzina"));
            TableColumn_Poniedzialek.setCellValueFactory(new PropertyValueFactory("pn"));
            TableColumn_Wtorek.setCellValueFactory(new PropertyValueFactory("wt"));
            TableColumn_Sroda.setCellValueFactory(new PropertyValueFactory("sr"));
            TableColumn_Czwartek.setCellValueFactory(new PropertyValueFactory("cz"));
            TableColumn_Piatek.setCellValueFactory(new PropertyValueFactory("pt"));
            
            TableColumn_Godzina.setCellFactory(godzinaFactory);
            TableColumn_Poniedzialek.setCellFactory(przedmiotFactory);
            TableColumn_Wtorek.setCellFactory(przedmiotFactory);
            TableColumn_Sroda.setCellFactory(przedmiotFactory);
            TableColumn_Czwartek.setCellFactory(przedmiotFactory);
            TableColumn_Piatek.setCellFactory(przedmiotFactory);

            TableView_PlanLekcji.getSelectionModel().setSelectionMode(SelectionMode.SINGLE);
            TableView_PlanLekcji.getSelectionModel().setCellSelectionEnabled(true);
            try {
                Odswiez();
            } catch (Exception e) {
                System.out.println("konstruktor OknoPlanLekcji");
            }
        }

        @Override
        final public void Odswiez() throws Exception {
            ArrayList<String> jednostki = SQLInterface.Planlekcji.PobierzJednostki();
            SQLInterface.Planlekcji.PobierzPlanLekcjiUcznia();
            ArrayList<SQLInterface.Planlekcji.RekordPlanuLekcji> plan = SQLInterface.Planlekcji.PobierzPlanLekcjiUcznia();
            ObservableList<RzadTabeliPlanuLekcji> daneDoTabeli = FXCollections.observableArrayList();
            for (int i = 0; i != jednostki.size(); i++) {
                RzadTabeliPlanuLekcji temp = new RzadTabeliPlanuLekcji(jednostki.get(i));
                for (SQLInterface.Planlekcji.RekordPlanuLekcji r : plan) {
                    if (r.jednostka == (i + 1)) {
                        switch (r.dzienTygodnia) {
                            case 1:
                                temp.przedmiotPoniedzialek.set(r.przedmiot);
                                break;

                            case 2:
                                temp.przedmiotWtorek.set(r.przedmiot);
                                break;

                            case 3:
                                temp.przedmiotSroda.set(r.przedmiot);
                                break;

                            case 4:
                                temp.przedmiotCzwartek.set(r.przedmiot);
                                break;

                            case 5:
                                temp.przedmiotPiatek.set(r.przedmiot);
                                break;

                            default:
                                System.out.println("Niewlasciwy dzien tygodnia w planie");
                        }
                    }
                }
                daneDoTabeli.add(temp);
            }
            TableView_PlanLekcji.setItems(daneDoTabeli);
        }

        public class RzadTabeliPlanuLekcji {

            StringProperty godzina;
            StringProperty przedmiotPoniedzialek;
            StringProperty przedmiotWtorek;
            StringProperty przedmiotSroda;
            StringProperty przedmiotCzwartek;
            StringProperty przedmiotPiatek;

            RzadTabeliPlanuLekcji(String godz, String pn, String wt, String sr, String czw, String pt) {
                godzina = new SimpleStringProperty(godz);
                przedmiotPoniedzialek = new SimpleStringProperty(pn);
                przedmiotWtorek = new SimpleStringProperty(wt);
                przedmiotSroda = new SimpleStringProperty(sr);
                przedmiotCzwartek = new SimpleStringProperty(czw);
                przedmiotPiatek = new SimpleStringProperty(pt);
            }

            RzadTabeliPlanuLekcji(String godz) {
                godzina = new SimpleStringProperty(godz);
                przedmiotPoniedzialek = new SimpleStringProperty("");
                przedmiotWtorek = new SimpleStringProperty("");
                przedmiotSroda = new SimpleStringProperty("");
                przedmiotCzwartek = new SimpleStringProperty("");
                przedmiotPiatek = new SimpleStringProperty("");
            }

            public StringProperty godzinaProperty() {
                return godzina;
            }

            public StringProperty pnProperty() {
                return przedmiotPoniedzialek;
            }

            public StringProperty wtProperty() {
                return przedmiotWtorek;
            }

            public StringProperty srProperty() {
                return przedmiotSroda;
            }

            public StringProperty czProperty() {
                return przedmiotCzwartek;
            }

            public StringProperty ptProperty() {
                return przedmiotPiatek;
            }
        }

        public class KomorkaGodziny<S, T> extends TableCell<RzadTabeliPlanuLekcji, String> {

            public KomorkaGodziny() {
                this.setAlignment(Pos.CENTER_RIGHT);
                this.setFont(Font.font(null, FontWeight.EXTRA_BOLD, USE_PREF_SIZE));
            }

            @Override
            public void updateItem(String item, boolean empty) {
                super.updateItem(item, empty);
                if (!empty) {
                    this.setText(item);
                }
            }
        }

        public class KomorkaPlanuLekcji<S, T> extends TableCell<RzadTabeliPlanuLekcji, String> {

            public KomorkaPlanuLekcji() {
                this.setAlignment(Pos.CENTER);
            }

            @Override
            public void updateItem(String item, boolean empty) {
                super.updateItem(item, empty);
                if (!empty) {
                    this.setText(item);
                }
            }
        }
    }

    public class OknoOcenyKoncowe extends Okno {

        final Group G_CzerwonyPasek;
        final TableView TV_OcenyKoncowe;
        final TableColumn TC_Przedmiot;
        final TableColumn TC_Nauczyciel;
        final TableColumn TC_OcenaKoncowa;
        final TableColumn TC_Zachowanie;
        final Label L_SredniaOcenKoncowych;
        final Label L_TwojWychowawca;
        final Label L_PrzedmiotyWychowawcy;
        final Label L_ZachowanieKoncowe;
        Callback<TableColumn, TableCell> ocenaFactory =
                new Callback<TableColumn, TableCell>() {
                    @Override
                    public TableCell call(TableColumn p) {
                        return new KomorkaOcenyKoncowej();
                    }
                };
        Callback<TableColumn, TableCell> zachowanieFactory =
                new Callback<TableColumn, TableCell>() {
                    @Override
                    public TableCell call(TableColumn p) {
                        return new KomorkaOcenyZachowania();
                    }
                };

        OknoOcenyKoncowe() {
            super("/gui_fxml/uczen_ocenykoncowe.fxml");
            G_CzerwonyPasek = (Group) elementy.get("Group_CzerwonyPasek");
            TV_OcenyKoncowe = (TableView) elementy.get("TableView_OcenyKoncowe");
            TC_Przedmiot = (TableColumn) elementy.get("TableColumn_Przedmiot");
            TC_Nauczyciel = (TableColumn) elementy.get("TableColumn_Nauczyciel");
            TC_OcenaKoncowa = (TableColumn) elementy.get("TableColumn_OcenaKoncowa");
            TC_Zachowanie = (TableColumn) elementy.get("TableColumn_Zachowanie");
            L_SredniaOcenKoncowych = (Label) elementy.get("Label_SredniaOcenkoncowych");
            L_TwojWychowawca = (Label) elementy.get("Label_Wychowawca");
            L_PrzedmiotyWychowawcy = (Label) elementy.get("Label_PrzedmiotWychowawcy");
            L_ZachowanieKoncowe = (Label) elementy.get("Label_OcenaKoncowaZZachowania");
            TC_Przedmiot.setCellValueFactory(new PropertyValueFactory("przedmiot"));
            TC_Nauczyciel.setCellValueFactory(new PropertyValueFactory("nauczyciel"));
            TC_OcenaKoncowa.setCellValueFactory(new PropertyValueFactory("ocenaKoncowa"));
            TC_Zachowanie.setCellValueFactory(new PropertyValueFactory("zachowanie"));
            TC_OcenaKoncowa.setCellFactory(ocenaFactory);
            TC_Zachowanie.setCellFactory(zachowanieFactory);
        }

        ObservableList<RekordTabeliOcenKoncowych> PobierzDane() {
            try {
                ObservableList<RekordTabeliOcenKoncowych> ret = FXCollections.observableArrayList();
                ArrayList<SQLInterface.OcenyKoncowe.RekordOcenKoncowych> dane = SQLInterface.OcenyKoncowe.PobierzOcenyKoncowe();
                System.out.println("SQL OK");
                for (int i = 0; i != dane.size(); i++) {
                    RekordTabeliOcenKoncowych temp = new RekordTabeliOcenKoncowych();
                    temp.nauczyciel.set(dane.get(i).nauczyciel);
                    temp.ocenaKoncowa.set(dane.get(i).ocena);
                    temp.przedmiot.set(dane.get(i).przedmiot);
                    temp.zachowanie.set(dane.get(i).zachowanie);
                    temp.ocenaKoncowaProponowanaProperty().set(dane.get(i).ocena_proponowana);
                    temp.ocenaKoncowaProponowanaProperty().set(dane.get(i).ocena_proponowana);
                    ret.add(temp);
                }
                return ret;
            } catch (Exception e) {
                System.out.println("Blad pobierania ocen koncowych");
                System.out.println(e.getMessage());
                return null;
            }
        }

        @Override
        final public void Odswiez() throws Exception {
            String[] daneWychowawcy = SQLInterface.DaneOsobowe.Uczen_PobierzDaneWychowawcy();
            ObservableList<RekordTabeliOcenKoncowych> daneDoTabeli = PobierzDane();
            TV_OcenyKoncowe.setItems(daneDoTabeli);

            L_PrzedmiotyWychowawcy.setText(daneWychowawcy[3]);
            L_TwojWychowawca.setText(daneWychowawcy[0] + " " + daneWychowawcy[1] + " " + daneWychowawcy[2]);
            L_ZachowanieKoncowe.setText(SQLInterface.OcenyKoncowe.PobierzZachowanieKoncowe());
            float sredniaOcenKoncowych = 0;
            int wystawionychOcen = 0;
            for (int i = 0; i != daneDoTabeli.size(); i++) {
                if (!daneDoTabeli.get(i).ocenaKoncowa.get().isEmpty()) {
                    wystawionychOcen++;
                    sredniaOcenKoncowych += Integer.parseInt(daneDoTabeli.get(i).ocenaKoncowa.get());
                }
            }
            if (wystawionychOcen == 0) {
                L_SredniaOcenKoncowych.setText("");
            } else {
                sredniaOcenKoncowych /= (float) wystawionychOcen;
                Format format = new DecimalFormat("#.##");
                String srednia = format.format(sredniaOcenKoncowych);
                sredniaOcenKoncowych *= 100;
                int sredniaInt = (int) sredniaOcenKoncowych;
                if (sredniaInt >= 475 && (L_ZachowanieKoncowe.getText().equals("wzorowe") || L_ZachowanieKoncowe.getText().equals("bardzo dobre"))) {
                    G_CzerwonyPasek.setVisible(true);
                } else {
                    G_CzerwonyPasek.setVisible(false);
                }
                L_SredniaOcenKoncowych.setText(srednia);
            }
        }

        String ObliczSredniaOcenKoncowych() {
            return null;
        }

        public class RekordTabeliOcenKoncowych {

            private StringProperty przedmiot;
            private StringProperty nauczyciel;
            private StringProperty ocenaKoncowa;
            private StringProperty zachowanie;
            private BooleanProperty ocenaKoncowaProponowana;
            private BooleanProperty zachowanieProponowane;

            public RekordTabeliOcenKoncowych() {
                przedmiot = new SimpleStringProperty();
                nauczyciel = new SimpleStringProperty();
                ocenaKoncowa = new SimpleStringProperty();
                zachowanie = new SimpleStringProperty();
                ocenaKoncowaProponowana = new SimpleBooleanProperty();
                zachowanieProponowane = new SimpleBooleanProperty();
            }

            public StringProperty przedmiotProperty() {
                return przedmiot;
            }

            public StringProperty nauczycielProperty() {
                return nauczyciel;
            }

            public StringProperty ocenaKoncowaProperty() {
                return ocenaKoncowa;
            }

            public StringProperty zachowanieProperty() {
                return zachowanie;
            }

            public BooleanProperty ocenaKoncowaProponowanaProperty() {
                return ocenaKoncowaProponowana;
            }

            public BooleanProperty zachowanieProponowaneProperty() {
                return zachowanieProponowane;
            }
        }

        public class KomorkaOcenyKoncowej<S, T> extends TableCell<RekordTabeliOcenKoncowych, String> {

            public KomorkaOcenyKoncowej() {
                this.setAlignment(Pos.CENTER);
                this.setFont(Font.font(null, FontWeight.EXTRA_BOLD, USE_PREF_SIZE));
            }

            @Override
            public void updateItem(String item, boolean empty) {
                super.updateItem(item, empty);
                if (!empty) {
                    this.setText(item);
                    if (this.getTableView().getItems().get(this.getIndex()).ocenaKoncowaProponowanaProperty().get()) {
                        this.setTextFill(Color.rgb(0xC0, 0x18, 0x18));
                    } else {
                        this.setTextFill(Color.rgb(0x18, 0x18, 0xF0));
                    }
                }
            }
        }

        public class KomorkaOcenyZachowania<S, T> extends TableCell<RekordTabeliOcenKoncowych, String> {

            public KomorkaOcenyZachowania() {
                this.setAlignment(Pos.CENTER);
                this.setFont(Font.font(null, FontWeight.EXTRA_BOLD, USE_PREF_SIZE));
            }

            @Override
            public void updateItem(String item, boolean empty) {
                super.updateItem(item, empty);
                if (!empty) {
                    this.setText(item);
                    if (this.getTableView().getItems().get(this.getIndex()).ocenaKoncowaProponowanaProperty().get()) {
                        this.setTextFill(Color.rgb(0xC0, 0x18, 0x18));
                    } else {
                        this.setTextFill(Color.rgb(0x18, 0x18, 0xF0));
                    }
                }
            }
        }
    }

    public class OknoZmianyHasla {

        public final Stage stage;
        public final FXMLLoader loader;
        public final AnchorPane parent;
        public final PasswordField pf_stare, pf_nowe1, pf_nowe2;
        public final Button b_ok, b_anuluj;
        public final Label l_bledy;
        public final Scene scene;

        OknoZmianyHasla() throws Exception {
            stage = new Stage(StageStyle.UTILITY);
            loader = new FXMLLoader(getClass().getResource("/gui_fxml/zmianahasla.fxml"));
            loader.load();
            parent = (AnchorPane) loader.getNamespace().get("AnchorPane_Parent");
            pf_stare = (PasswordField) loader.getNamespace().get("PasswordField_StareHaslo");
            pf_nowe1 = (PasswordField) loader.getNamespace().get("PasswordField_NoweHaslo1");
            pf_nowe2 = (PasswordField) loader.getNamespace().get("PasswordField_NoweHaslo2");
            b_ok = (Button) loader.getNamespace().get("Button_ZmianaHasla_OK");
            b_anuluj = (Button) loader.getNamespace().get("Button_ZmianaHasla_Anuluj");
            l_bledy = (Label) loader.getNamespace().get("Label_Bledy");
            l_bledy.setText("");
            l_bledy.setVisible(true);

            b_ok.setOnAction(handler_b_ok);
            b_anuluj.setOnAction(handler_b_anuluj);

            scene = new Scene(parent, 200, 160);
            stage.setScene(scene);
            stage.setTitle("Zmiana hasła");
            stage.setResizable(false);
            stage.show();
        }
        EventHandler<ActionEvent> handler_b_anuluj = new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                try {
                    stage.close();
                } catch (Exception e) {
                }
            }
        };
        EventHandler<ActionEvent> handler_b_ok = new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                System.out.println(pf_stare.getText());
                System.out.println(pf_nowe1.getText());
                System.out.println(pf_nowe2.getText());
                System.out.println(pf_stare);
                System.out.println(pf_nowe1);
                System.out.println(pf_nowe2);
                System.out.println(l_bledy.getText());
                System.out.println(l_bledy);
                try {
                    if (pf_stare.getText().isEmpty()
                            || pf_nowe1.getText().isEmpty()
                            || pf_nowe2.getText().isEmpty()) {
                        l_bledy.setText("Wypełnij wszystkie pola!");
                        System.out.println("puste pole");
                    } else if (pf_nowe1.getText() == null ? pf_nowe2.getText() != null : !pf_nowe1.getText().equals(pf_nowe2.getText())) {
                        l_bledy.setText("Nowe hasła są różne!");
                        System.out.println("nowe hasla nie sa identyczne");
                    } else {
                        boolean ok = SQLInterface.ZmienHaslo(pf_stare.getText(), pf_nowe1.getText());
                        System.out.println("odpowiedz bazy danych: " + ok);
                        if (!ok) {
                            l_bledy.setText("Niewłaściwe stare hasło!");
                        } else {
                            stage.close();
                        }
                    }
                } catch (Exception e) {
                    System.out.println("handler zmiana hasla: " + e.getMessage());
                    e.printStackTrace(System.out);
                }
            }
        };
    }
}